#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <time.h> 
#include <stdarg.h>

#define PORT 10086
#define BUFFER_SIZE 4096
#define MAX_CLIENTS 20
#define DEVICE_ID_LEN 10
#define CONNECT_PREFIX "CONNECT:"
#define ROLE_RED "ROLE:RED"
#define ROLE_BLACK "ROLE:BLACK"
#define ROLE_SPECTATOR "ROLE:SPECTATOR"
#define MOVE_PREFIX "MOVE:"
#define HEARTBEAT_PREFIX "HEARTBEAT:"
#define INIT_BOARD_PREFIX "INIT_BOARD"
#define RESET_COMMAND "RESET_BOARD"
#define STEP_BOARD_PREFIX "STEP"
#define BACK_COMMAND "BACK_BOARD"
#define MAX_HISTORY 100
//////////////////// 处理通信 /////////////////////
// 客户端角色
typedef enum {
    ROLE_NONE,
    ROLE_RED_PLAYER,
    ROLE_BLACK_PLAYER,
    ROLE_SPECTATOR_PLAYER
} ClientRole;

// 客户端地址结构
struct Client {
    struct sockaddr_in addr;
    int active;
    ClientRole role;
    time_t last_heartbeat;
    char device_id[DEVICE_ID_LEN];
    int privilege;
};

char red_device_id[DEVICE_ID_LEN];
char black_device_id[DEVICE_ID_LEN];
struct Client clients[MAX_CLIENTS];
int client_count = 0;
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
int sockfd;
    
//////////////////// 处理象棋 /////////////////////
typedef struct {
    int board[9][10];  // 0表示空
    int current_turn;  // 1:红方回合, 2:黑方回合, 3:红方胜利, 4:黑方胜利
} ChessState;

ChessState chess_state;
pthread_mutex_t chess_mutex = PTHREAD_MUTEX_INITIALIZER;

// 历史数据，用于悔棋
typedef struct {
    ChessState state;
    int toX;
    int toY;
} HistoryRecord;
HistoryRecord history_stack[MAX_HISTORY];
int history_top = -1;

//////////////////// 公共函数和定义 /////////////////////
void computerMove();
// 记录日志
void log_message(const char* format, ...) {
    FILE* log_file = fopen("app.log", "a");
    if (log_file == NULL) {
        perror("open log fail");
        return;
    }
    
    // 获取当前时间
    time_t now;
    time(&now);
    struct tm* timeinfo = localtime(&now);
    char time_str[20];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", timeinfo);
    
    // 打印时间和日志级别
    fprintf(log_file, "[%s] ", time_str);
    
    // 处理可变参数
    va_list args;
    va_start(args, format);
    vfprintf(log_file, format, args);
    va_end(args);
    
    // 添加换行符
    fprintf(log_file, "\n");
    
    // 关闭文件
    fclose(log_file);
}

//  生成棋盘初始化信息
void generateInitBoardMessage(char *buffer, ClientRole role, ChessState *state) {
    // 格式: INIT_BOARD:角色:当前回合:棋子数据(90个数字)
    int pos = sprintf(buffer, "%s:%d:%d:", INIT_BOARD_PREFIX, role, state->current_turn);
    
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 9; x++) {
            pos += sprintf(buffer + pos, "%d,", state->board[x][y]);
        }
    }
    buffer[pos - 1] = '\0';
}

void generateStepMessage(char *buffer, int toX, int toY, ChessState *state) {
    // 格式: STEP:red:black:all:最后位置:当前回合:棋子数据(90个数字)
    int pos = sprintf(buffer, "%s:%s:%s:%d:%d,%d:%d:", 
        STEP_BOARD_PREFIX, 
        red_device_id, black_device_id,
        client_count,
        toX, toY, state->current_turn);
    //log_message("player:%s %s", red_device_id, black_device_id);
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 9; x++) {
            pos += sprintf(buffer + pos, "%d,", state->board[x][y]);
        }
    }
    buffer[pos - 1] = '\0';
}

//////////////////// 处理通信 /////////////////////
void getRoleIndex(int *redIndex, int *blackIndex) {
    for (int i = 0; i < client_count; i++) {
        if (clients[i].active) {
            if (clients[i].role == ROLE_RED_PLAYER) {
                *redIndex = i;
            }
            if (clients[i].role == ROLE_BLACK_PLAYER) {
                *blackIndex = i;
            }
        }
    }
}

// 分配角色 
ClientRole assignRole() {
    int redIndex = -1;
    int blackIndex = -1;

    getRoleIndex(&redIndex, &blackIndex);

    if (redIndex == -1) {
        return ROLE_RED_PLAYER;
    }
    if (blackIndex == -1) {
        return ROLE_BLACK_PLAYER;
    }
    return ROLE_SPECTATOR_PLAYER;
}

void send_init_msg(ClientRole role, struct sockaddr * addr) {
    char init_msg[BUFFER_SIZE];
    generateInitBoardMessage(init_msg, role, &chess_state);
    sendto(sockfd, init_msg, strlen(init_msg), 0, addr, sizeof(struct sockaddr_in));
}

// 添加客户端到列表
void add_client(struct sockaddr_in *addr, char * device_id) {
    pthread_mutex_lock(&clients_mutex);
    pthread_mutex_lock(&chess_mutex);  // 锁定棋盘状态

    // 检查是否已存在
    for (int i = 0; i < client_count; i++) {
        if (memcmp(&clients[i].addr, addr, sizeof(struct sockaddr_in)) == 0) {
            clients[i].active = 1;
            clients[i].last_heartbeat = time(NULL);
            pthread_mutex_unlock(&chess_mutex);
            pthread_mutex_unlock(&clients_mutex);
            return;
        }
        if (strcmp(clients[i].device_id, device_id) == 0) {        
            clients[i].addr = *addr;
            clients[i].active = 1;
            clients[i].last_heartbeat = time(NULL);
            pthread_mutex_unlock(&chess_mutex);
            pthread_mutex_unlock(&clients_mutex);
            log_message("Reconnect %s %s:%d (%d)", device_id,
               inet_ntoa(clients[i].addr.sin_addr),
               ntohs(clients[i].addr.sin_port), client_count);
            // 发送包含角色、棋盘状态和当前回合的初始化信息
            send_init_msg(clients[i].role, (struct sockaddr *)addr);
            return;
        }
    }
    
    // 添加新客户端
    if (client_count < MAX_CLIENTS) {
        int i = client_count;
        clients[i].addr = *addr;
        clients[i].active = 1;
        clients[i].role = assignRole();
        clients[i].last_heartbeat = time(NULL);
        clients[i].privilege = 0;
        strncpy(clients[i].device_id, device_id, DEVICE_ID_LEN - 1);
        clients[i].device_id[DEVICE_ID_LEN - 1] = '\0';
        if (clients[i].role == ROLE_RED_PLAYER) {
            strcpy(red_device_id, clients[i].device_id);
        } else if (clients[i].role == ROLE_BLACK_PLAYER) {
            strcpy(black_device_id, clients[i].device_id);
        }
        client_count++;
        log_message("New client %s %s:%d (%d)", device_id,
           inet_ntoa(clients[i].addr.sin_addr),
           ntohs(clients[i].addr.sin_port), client_count);

        // 发送包含角色、棋盘状态和当前回合的初始化信息
        send_init_msg(clients[i].role, (struct sockaddr *)addr);
    } else {
        log_message("Max clients reached. Rejected new connection.");
    }

    pthread_mutex_unlock(&chess_mutex);
    pthread_mutex_unlock(&clients_mutex);
}

// 转发数据到所有客户端 
void forward_data(char *buffer, int len, struct sockaddr_in *sender_addr, int sockfd) {
    pthread_mutex_lock(&clients_mutex);

    for (int i = 0; i < client_count; i++) {
        if (clients[i].active &&
            (sender_addr == NULL || 
            memcmp(&clients[i].addr, sender_addr, sizeof(struct sockaddr_in)) != 0)) {

            if (sendto(sockfd, buffer, len, 0,
                       (struct sockaddr *)&clients[i].addr,
                       sizeof(struct sockaddr_in)) < 0) {
                perror("sendto failed");
                clients[i].active = 0;
            }
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

int getNewOneIndex() {
    int minPrivilege = 20;      // 最小权限值
    int selectedIndex = -1;          // 选中的客户端索引
    int maxPrivilege = 0;      // 最大权限值（用于后续计算）
    int activeCount = 0;             // 活跃客户端数量
    
    // 一次遍历完成：查找最小权限客户端、统计最大权限值和活跃客户端数量
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].active && clients[i].role == ROLE_SPECTATOR_PLAYER) {
            activeCount++;
            
            // 记录最小权限及索引（首个）
            if (clients[i].privilege < minPrivilege) {
                minPrivilege = clients[i].privilege;
                selectedIndex = i;
            }
            
            // 记录最大权限值
            if (clients[i].privilege > maxPrivilege) {
                maxPrivilege = clients[i].privilege;
            }
        }
    }
    
    // 没有活跃客户端
    if (selectedIndex == -1) {
        return -1;
    }
    
    // 如果只有一个活跃客户端
    if (activeCount == 1) {
        return selectedIndex;
    }
    
    // 计算剩余客户端的最大权限值（原最大值 - 选中的权限值）
    int remainingMax = maxPrivilege - minPrivilege;
    
    // 第二次遍历：更新所有客户端权限
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].active && clients[i].role == ROLE_SPECTATOR_PLAYER) {
            clients[i].privilege -= minPrivilege;
            
            // 单独处理选中的客户端
            if (i == selectedIndex) {
                clients[i].privilege = remainingMax + 1;
            }
        }
    }
    
    return selectedIndex;
}

// 从旁观者中选择替补 
void replaceDisconnectedPlayer(ClientRole role) {
    int i = getNewOneIndex();
    if (i == -1) {
        return;
    }
    clients[i].role = role; 
    if (clients[i].role == ROLE_RED_PLAYER) {
        strcpy(red_device_id, clients[i].device_id);
    } else if (clients[i].role == ROLE_BLACK_PLAYER) {
        strcpy(black_device_id, clients[i].device_id);
    }
    char buffer[BUFFER_SIZE];
    generateInitBoardMessage(buffer, role, &chess_state);
    sendto(sockfd, buffer, strlen(buffer), 0,
           (struct sockaddr *)&clients[i].addr, sizeof(struct sockaddr_in));
    log_message("Reassigned %s as %s", clients[i].device_id, role == ROLE_RED_PLAYER ? "red" : "black");
}

//////////////////// 处理象棋 /////////////////////

// 初始化棋盘 
void initChessState() {
    memset(&chess_state, 0, sizeof(ChessState));

    chess_state.board[4][9] = 1;    // 帅
    chess_state.board[3][9] = 2;    // 仕
    chess_state.board[5][9] = 3;    // 仕
    chess_state.board[2][9] = 4;    // 相
    chess_state.board[6][9] = 5;    // 相
    chess_state.board[1][9] = 6;    // 马
    chess_state.board[7][9] = 7;    // 马
    chess_state.board[0][9] = 8;    // 车
    chess_state.board[8][9] = 9;    // 车
    chess_state.board[1][7] = 10;   // 炮
    chess_state.board[7][7] = 11;   // 炮
    chess_state.board[0][6] = 12;   // 兵
    chess_state.board[2][6] = 13;   // 兵
    chess_state.board[4][6] = 14;   // 兵
    chess_state.board[6][6] = 15;   // 兵
    chess_state.board[8][6] = 16;   // 兵

    chess_state.board[4][0] = 17;   // 将
    chess_state.board[3][0] = 18;   // 士
    chess_state.board[5][0] = 19;   // 士
    chess_state.board[2][0] = 20;   // 象
    chess_state.board[6][0] = 21;   // 象
    chess_state.board[1][0] = 22;   // 马
    chess_state.board[7][0] = 23;   // 马
    chess_state.board[0][0] = 24;   // 车
    chess_state.board[8][0] = 25;   // 车
    chess_state.board[1][2] = 26;   // 炮
    chess_state.board[7][2] = 27;   // 炮
    chess_state.board[0][3] = 32;   // 卒
    chess_state.board[2][3] = 28;   // 卒
    chess_state.board[4][3] = 29;   // 卒
    chess_state.board[6][3] = 30;   // 卒
    chess_state.board[8][3] = 31;   // 卒

    chess_state.current_turn = 1;   // 红方先行
    history_top = -1;
}


// 重置棋盘并通知所有客户端
void resetBoard() {
    int last_turn;
    
    // 重新初始化棋盘
    pthread_mutex_lock(&chess_mutex);
    last_turn = chess_state.current_turn;
    initChessState();
    pthread_mutex_unlock(&chess_mutex);

    // 发送重置通知消息
    char stepMsg[BUFFER_SIZE];
    generateStepMessage(stepMsg, -1, -1, &chess_state);
    forward_data(stepMsg, strlen(stepMsg), NULL, sockfd);
    log_message("Board reset successfully");
    
    // 在输棋场景换人
    pthread_mutex_lock(&chess_mutex);
    if (client_count > 2 && last_turn > 2) {
        int redIndex = -1;
        int blackIndex = -1;
        int target;
        ClientRole role;
        char init_msg[BUFFER_SIZE];
        
        getRoleIndex(&redIndex, &blackIndex);
        target = redIndex;
        role = ROLE_RED_PLAYER;
        if (last_turn == 4) {
            target = blackIndex;
            role = ROLE_BLACK_PLAYER;
        }        
        replaceDisconnectedPlayer(role);
        
        generateInitBoardMessage(init_msg, ROLE_SPECTATOR_PLAYER, &chess_state);
        sendto(sockfd, init_msg, strlen(init_msg), 0,
               (struct sockaddr *)&clients[target].addr, sizeof(struct sockaddr_in));  
    }
    pthread_mutex_unlock(&chess_mutex);
}

// 悔棋棋盘并通知所有客户端
void backBoard(ClientRole role) {
    pthread_mutex_lock(&chess_mutex);
    
    int backCount = 1;
    if ((role == ROLE_RED_PLAYER && (chess_state.current_turn == 1 || chess_state.current_turn == 4)) ||
        (role == ROLE_BLACK_PLAYER && (chess_state.current_turn == 2 || chess_state.current_turn == 3))) {
        backCount = 2;
    }
    
    // 检查是否有可悔棋的历史记录
    if (history_top >= backCount) {
        // 恢复上一个状态
        chess_state = history_stack[history_top - backCount].state;
        // 获取该状态对应的最后一步坐标
        int toX = history_stack[history_top - backCount].toX;
        int toY = history_stack[history_top - backCount].toY;
                
        // 栈顶指针下移
        history_top = history_top - backCount;
        
        // 生成悔棋后的棋盘状态消息（使用备份的坐标）
        char stepMsg[BUFFER_SIZE];
        generateStepMessage(stepMsg, toX, toY, &chess_state);
        forward_data(stepMsg, strlen(stepMsg), NULL, sockfd);
    } else {
        log_message("No history to roll back");
    }
    
    pthread_mutex_unlock(&chess_mutex);
}

void change_role(int i, ClientRole role) {
    char buffer[BUFFER_SIZE];

    clients[i].role = role;
    if (role == ROLE_RED_PLAYER) {
        strcpy(red_device_id, clients[i].device_id);
    } else if (role == ROLE_BLACK_PLAYER) {
        strcpy(black_device_id, clients[i].device_id);
    }

    generateInitBoardMessage(buffer, role, &chess_state);
    sendto(sockfd, buffer, strlen(buffer), 0,
           (struct sockaddr *)&clients[i].addr, sizeof(struct sockaddr_in));
}

// 心跳检查线程函数
void *heartbeat_check_thread() {
    int kick_count = 0;
    int last_history_top = -1;
    int has_player_out = 0;
    
    while (1) {
        sleep(10);  // 每10秒检查一次
        has_player_out = 0;
        time_t current_time = time(NULL);
        
        pthread_mutex_lock(&clients_mutex);
        for (int i = 0; i < client_count; i++) {
            if (!clients[i].active) {
                continue;
            }

            // 计算距离最后一次心跳的时间差
            double elapsed = difftime(current_time, clients[i].last_heartbeat);

            if (elapsed > 20) {  // 超过20秒未收到心跳
                log_message("Client %s:%d heartbeat lost",
                       inet_ntoa(clients[i].addr.sin_addr),
                       ntohs(clients[i].addr.sin_port));

                // 如果是玩家角色，重新选择玩家
                if (clients[i].role == ROLE_RED_PLAYER || 
                    clients[i].role == ROLE_BLACK_PLAYER) {
                    replaceDisconnectedPlayer(clients[i].role);
                    has_player_out = 1;
                }

                // 移除客户端（将最后一个客户端移到当前位置）
                if (i < client_count - 1) {
                    clients[i] = clients[client_count - 1];
                }
                client_count--;
                i--;  // 回退索引，避免跳过元素
            }
        }
        
        kick_count++;
        if (kick_count == 1) {
            last_history_top = history_top;
        }
        // 300秒内没有动作，就换人
        if (kick_count == 23) {
            if (last_history_top == history_top) {
                if (client_count > 2) {
                    for (int i = 0; i < client_count; i++) {
                        if (!clients[i].active) {
                            continue;
                        }
                        if (chess_state.current_turn == 1) {
                            replaceDisconnectedPlayer(ROLE_RED_PLAYER);
                            break;
                        }
                        if (chess_state.current_turn == 2) {
                            replaceDisconnectedPlayer(ROLE_BLACK_PLAYER);
                            break;
                        } 
                    }
                } else if(client_count == 1) {
                    int redIndex = -1;
                    int blackIndex = -1;
                    getRoleIndex(&redIndex, &blackIndex);
                    if (blackIndex != -1) {
                        black_device_id[0] = '\0';
                        change_role(blackIndex, ROLE_RED_PLAYER);
                        log_message("change %s to red", clients[blackIndex].device_id);
                    }
                }
            }
        }
        if (kick_count > 25) {
            kick_count = 0;
        }
        pthread_mutex_unlock(&clients_mutex);
        
        if (has_player_out == 1 && client_count == 1 && chess_state.current_turn == 2) {
            computerMove();
        }
    }
    return NULL;
}



// 以下是各棋子的移动规则检查函数（简化实现）
int isKingMoveValid(int fromX, int fromY, int toX, int toY, int piece) {
    // 帅/将只能上下左右走一步，且在九宫格内
    int dx = abs(fromX - toX);
    int dy = abs(fromY - toY);
    if ((dx == 1 && dy == 0) || (dx == 0 && dy == 1)) {
        // 检查九宫格范围
        int min_x = 3, max_x = 5;
        int min_y, max_y;
        if (piece == 1) { // 红帅
            min_y = 7; max_y = 9;
        } else { // 黑将
            min_y = 0; max_y = 2;
        }
        return (toX >= min_x && toX <= max_x && toY >= min_y && toY <= max_y);
    }
    return 0;
}

int isAdvisorMoveValid(int fromX, int fromY, int toX, int toY, int piece) {
    // 仕/士只能斜走一步，且在九宫格内
    int dx = abs(fromX - toX);
    int dy = abs(fromY - toY);
    if (dx == 1 && dy == 1) {
        // 检查九宫格范围
        int min_x = 3, max_x = 5;
        int min_y, max_y;
        if (piece == 2 || piece == 3) { // 红仕
            min_y = 7; max_y = 9;
        } else { // 黑士
            min_y = 0; max_y = 2;
        }
        return (toX >= min_x && toX <= max_x && toY >= min_y && toY <= max_y);
    }
    return 0;
}

int isElephantMoveValid(int fromX, int fromY, int toX, int toY, int piece, ChessState *state) {
    // 相/象走田字格，不能过河
    int dx = abs(fromX - toX);
    int dy = abs(fromY - toY);
    if (dx == 2 && dy == 2) {
        // 检查河界（红相不能过河，黑象不能过河）
        if ((piece == 4 || piece == 5) && toY <= 4) {
            return 0; // 红相过河
        }
        if ((piece == 20 || piece == 21) && toY >= 5) {
            return 0; // 黑象过河
        }
        
        // 检查田字格中心是否有棋子（绊象腿）
        int mid_x = (fromX + toX) / 2;
        int mid_y = (fromY + toY) / 2;
        return (state->board[mid_x][mid_y] == 0);
    }
    return 0;
}

int isHorseMoveValid(int fromX, int fromY, int toX, int toY, ChessState *state) {
    // 马走日字格，检查马腿
    int dx = abs(fromX - toX);
    int dy = abs(fromY - toY);
    if ((dx == 1 && dy == 2) || (dx == 2 && dy == 1)) {
        // 检查马腿
        if (dx == 2) {
            int leg_x = (fromX < toX) ? fromX + 1 : fromX - 1;
            if (state->board[leg_x][fromY] != 0) return 0;
        } else {
            int leg_y = (fromY < toY) ? fromY + 1 : fromY - 1;
            if (state->board[fromX][leg_y] != 0) return 0;
        }
        return 1;
    }
    return 0;
}

int isChariotMoveValid(int fromX, int fromY, int toX, int toY, ChessState *state) {
    // 车走直线，不能有棋子阻挡
    if (fromX != toX && fromY != toY) {
        return 0; // 不是直线
    }
    
    // 检查路径上是否有棋子
    if (fromX == toX) { // 水平移动
        int min_y = (fromY < toY) ? fromY : toY;
        int max_y = (fromY > toY) ? fromY : toY;
        for (int y = min_y + 1; y < max_y; y++) {
            if (state->board[fromX][y] != 0) {
                return 0;
            }
        }
    } else { // 垂直移动
        int min_x = (fromX < toX) ? fromX : toX;
        int max_x = (fromX > toX) ? fromX : toX;
        for (int x = min_x + 1; x < max_x; x++) {
            if (state->board[x][fromY] != 0) {
                return 0;
            }
        }
    }
    return 1;
}

int isCannonMoveValid(int fromX, int fromY, int toX, int toY, ChessState *state) {
    // 炮走直线，吃子需有炮架
    if (fromX != toX && fromY != toY) return 0; // 不是直线
    
    int obstacle_count = 0;
    // 计算路径上的障碍物数量
    if (fromX == toX) { // 水平移动
        int min_y = (fromY < toY) ? fromY : toY;
        int max_y = (fromY > toY) ? fromY : toY;
        for (int y = min_y + 1; y < max_y; y++) {
            if (state->board[fromX][y] != 0) obstacle_count++;
        }
    } else { // 垂直移动
        int min_x = (fromX < toX) ? fromX : toX;
        int max_x = (fromX > toX) ? fromX : toX;
        for (int x = min_x + 1; x < max_x; x++) {
            if (state->board[x][fromY] != 0) obstacle_count++;
        }
    }
    
    // 炮不吃子时无障碍物，吃子时刚好一个障碍物
    int target = state->board[toX][toY];
    if (target == 0) {
        return (obstacle_count == 0);
    } else {
        return (obstacle_count == 1);
    }
}

int isPawnMoveValid(int fromX, int fromY, int toX, int toY, int piece) {
    // 兵/卒前进不后退，过河后可以左右走
    int dx = abs(fromX - toX);
    int dy = abs(fromY - toY);
    if (dx + dy != 1) {
        return 0; // 只能走一步
    }
    
    // 红兵（12-16）向下走，黑卒（28-32）向上走
    if (piece >= 12 && piece <= 16) { // 红兵
        if (toY > fromY) 
            return 0; // 不能后退
        if (dx == 1 && fromY > 4) 
            return 0; // 没过河不能左右走
    } else { // 黑卒
        if (toY < fromY) 
            return 0; // 不能后退
        if (dx == 1 && fromY < 5) 
            return 0; // 没过河不能左右走
    }
    return 1;
}


int checkKingFaceoff(ChessState* state) {
    int red_king_x = -1, red_king_y = -1;  // 红帅位置
    int black_king_x = -1, black_king_y = -1;  // 黑将位置

    // 1. 找到红帅（1）和黑将（17）的位置
    for (int x = 0; x < 9; x++) {
        for (int y = 0; y < 10; y++) {
            if (state->board[x][y] == 1) {  // 红帅
                red_king_x = x;
                red_king_y = y;
            } else if (state->board[x][y] == 17) {  // 黑将
                black_king_x = x;
                black_king_y = y;
            }
        }
    }

    if (red_king_x == -1 || black_king_x == -1) {
        return 0;
    }

    if (red_king_x != black_king_x) {
        return 0;
    }

    int min_y = (red_king_y < black_king_y) ? red_king_y : black_king_y;
    int max_y = (red_king_y > black_king_y) ? red_king_y : black_king_y;

    for (int y = min_y + 1; y < max_y; y++) {
        if (state->board[red_king_x][y] != 0) {
            return 0;
        }
    }

    return 1;
}

// 检查棋子是否能从(fromX,fromY)移动到(toX,toY)
int isValidPieceMove(int fromX, int fromY, int toX, int toY, int piece, ChessState *state) {
    // 位置相同无效
    if (fromX == toX && fromY == toY) {
        return 0;
    }
    
    // 目标位置是己方棋子无效
    int is_red = (piece >= 1 && piece <= 16);
    int target = state->board[toX][toY];
    if (target != 0) {
        if ((is_red && target >= 1 && target <= 16) || 
            (!is_red && target >= 17 && target <= 32)) {
            return 0;
        }
    }
    
    // 复制当前状态用于对帅判断
    ChessState temp_state = *state;
    temp_state.board[toX][toY] = piece;
    temp_state.board[fromX][fromY] = 0;
    if (checkKingFaceoff(&temp_state) == 1) {
        // 有对帅的情况
        return 0;
    }
    
    // 根据不同棋子类型检查移动规则（简化版）
    switch (piece) {
        case 1:  // 红帅
        case 17: // 黑将
            return isKingMoveValid(fromX, fromY, toX, toY, piece);
        case 2: 
        case 3:  // 红仕
        case 18:
        case 19: // 黑士
            return isAdvisorMoveValid(fromX, fromY, toX, toY, piece);
        case 4:
        case 5:   // 红相
        case 20:
        case 21: // 黑象
            return isElephantMoveValid(fromX, fromY, toX, toY, piece, state);
        case 6:
        case 7:   // 红马
        case 22:
        case 23: // 黑马
            return isHorseMoveValid(fromX, fromY, toX, toY, state);
        case 8:
        case 9:   // 红车
        case 24:
        case 25: // 黑车
            return isChariotMoveValid(fromX, fromY, toX, toY, state);
        case 10:
        case 11: // 红炮
        case 26:
        case 27: // 黑炮
            return isCannonMoveValid(fromX, fromY, toX, toY, state);
        case 12:
        case 13:
        case 14:
        case 15:
        case 16: // 红兵
        case 28:
        case 29:
        case 30:
        case 31:
        case 32: // 黑卒
            return isPawnMoveValid(fromX, fromY, toX, toY, piece);
        default:
            return 0;
    }
}

// 检查移动是否有效 
int isValidMove(int fromX, int fromY, int toX, int toY, ClientRole role) {
    int piece = chess_state.board[fromX][fromY];
    if (piece == 0) {
        return 0;
    }
    if (fromX == toX && fromY == toY) {
        return 0;
    }

    if ((role == ROLE_RED_PLAYER && piece > 16) ||
        (role == ROLE_BLACK_PLAYER && piece <= 16)) {
        return 0;
    }

    if ((role == ROLE_RED_PLAYER && chess_state.current_turn != 1) ||
        (role == ROLE_BLACK_PLAYER && chess_state.current_turn != 2)) {
        return 0;
    }
    
    return 1;
}

// 检查攻击路径（用于判断将军）
int canAttack(int fromX, int fromY, int toX, int toY, int piece, ChessState *state) {
    // 攻击逻辑同移动逻辑，但目标固定为将帅
    return isValidPieceMove(fromX, fromY, toX, toY, piece, state);
}

// 检查将帅是否被将军
int isKingInCheck(int x, int y, int side, ChessState *state) {
    // 检查对方棋子是否能攻击到当前将帅
    int enemy_min, enemy_max;
    if (side == 1) {
        enemy_min = 17; // 黑方棋子范围
        enemy_max = 32;
    } else {
        enemy_min = 1;  // 红方棋子范围
        enemy_max = 16;
    }
    
    // 检查所有敌方棋子是否能攻击到将帅位置
    for (int ey = 0; ey < 10; ey++) {
        for (int ex = 0; ex < 9; ex++) {
            int piece = state->board[ex][ey];
            if (piece >= enemy_min && piece <= enemy_max) {
                if (canAttack(ex, ey, x, y, piece, state)) {
                    return 1; // 被将军
                }
            }
        }
    }
    return 0; // 未被将军
}

// 检查是否有棋子可以挡将或吃子解围
int hasBlockingPiece(int king_x, int king_y, int side, ChessState *state) {
    int friend_min, friend_max;
    if (side == 1) {
        friend_min = 1; 
        friend_max = 16;

    } else {
        friend_min = 17; 
        friend_max = 32;
    }
    
    // 遍历所有己方棋子
    for (int fx = 0; fx < 9; fx++) {
        for (int fy = 0; fy < 10; fy++) {
            int piece = state->board[fx][fy];
            if (piece < friend_min || piece > friend_max) {
                continue; // 不是己方棋子
            }
            if (piece == 1 || piece == 17) {
                continue; // 跳过将帅自身
            }
            
            // 尝试移动己方棋子到所有可能位置
            for (int tx = 0; tx < 9; tx++) {
                for (int ty = 0; ty < 10; ty++) {
                    // 目标位置是己方棋子则跳过
                    int target = state->board[tx][ty];
                    if (target >= friend_min && target <= friend_max) {
                        continue;
                    }
                    
                    // 检查该棋子是否能移动到目标位置
                    if (!isValidPieceMove(fx, fy, tx, ty, piece, state)) {
                        continue;
                    }
                    
                    // 模拟移动
                    int original_target = state->board[tx][ty];
                    state->board[tx][ty] = piece;
                    state->board[fx][fy] = 0;
                    
                    // 检查移动后将帅是否仍被将军
                    int still_in_check = isKingInCheck(king_x, king_y, side, state);
                    
                    // 恢复棋盘
                    state->board[fx][fy] = piece;
                    state->board[tx][ty] = original_target;
                    
                    if (!still_in_check) {
                        return 1; // 有解围方法
                    }
                }
            }
        }
    }
    
    return 0;
}

// 检查将帅是否有有效逃脱位置
int hasValidEscape(int x, int y, int side, ChessState *state) {
    // 将帅的移动范围（九宫格）
    int min_x, max_x, min_y, max_y;
    if (side == 1) { // 红方帅
        min_x = 3; max_x = 5;
        min_y = 7; max_y = 9;
    } else { // 黑方将
        min_x = 3; max_x = 5;
        min_y = 0; max_y = 2;
    }
    
    // 尝试上下左右移动一步
    int dx[] = {0, 0, -1, 1};
    int dy[] = {-1, 1, 0, 0};
    
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        
        // 检查是否在九宫格内
        if (nx < min_x || nx > max_x || ny < min_y || ny > max_y) {
            continue;
        }
        
        // 检查目标位置是否有己方棋子
        int target = state->board[nx][ny];
        if ((side == 1 && target >= 1 && target <= 16) || 
            (side == 2 && target >= 17 && target <= 32)) {
            continue;
        }
        
        // 模拟移动后检查是否仍被将军
        int original = state->board[nx][ny];
        state->board[nx][ny] = (side == 1) ? 1 : 17;
        state->board[x][y] = 0;
        
        int still_in_check = isKingInCheck(nx, ny, side, state);
        
        // 恢复棋盘状态
        state->board[x][y] = (side == 1) ? 1 : 17;
        state->board[nx][ny] = original;
        
        if (!still_in_check) {
            return 1; // 有有效逃脱位置
        }
    }
    
    // 检查是否有己方棋子可以挡将或吃子解围
    if (hasBlockingPiece(x, y, side, state)) {
        return 1;
    }
    
    return 0; // 无有效逃脱方式
}

int checkEndGame(ChessState *state) {
    // 查找红方帅和黑方将的位置
    int red_king_x = -1, red_king_y = -1;
    int black_king_x = -1, black_king_y = -1;
    
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 9; x++) {
            if (state->board[x][y] == 1) {       // 红方帅
                red_king_x = x;
                red_king_y = y;
            } else if (state->board[x][y] == 17) {  // 黑方将
                black_king_x = x;
                black_king_y = y;
            }
        }
    }
    
    // 帅或将不存在（已被吃掉），直接判定胜负
    if (red_king_x == -1) {
        return 2;  // 红帅被吃，黑方胜
    }
    if (black_king_x == -1) {
        return 1; // 黑将被吃，红方胜
    }
    
    // 根据当前回合判断是否被将死
    if (state->current_turn == 1) {
        // 红方回合：检查红帅是否被将死
        if (isKingInCheck(red_king_x, red_king_y, 1, state) && 
            !hasValidEscape(red_king_x, red_king_y, 1, state)) {
            return 2; // 红帅无法逃脱，黑方胜
        }
    } else {
        // 黑方回合：检查黑将是否被将死
        if (isKingInCheck(black_king_x, black_king_y, 2, state) && 
            !hasValidEscape(black_king_x, black_king_y, 2, state)) {
            return 1; // 黑将无法逃脱，红方胜
        }
    }
    
    return 0; // 游戏未结束
}

void moveChess(int fromX, int fromY, int toX, int toY, int *needComputeHelp){
    char stepMsg[BUFFER_SIZE];
    
    // 将帅被吃，直接判断胜负
    int finished = 0;
    if (chess_state.board[toX][toY] == 17) {
        // 红方胜利
        finished = 3;
    }
    else if (chess_state.board[toX][toY] == 1) {
        // 黑方胜利
        finished = 4;
    }
    
    // 更新棋盘
    chess_state.board[toX][toY] = chess_state.board[fromX][fromY];
    chess_state.board[fromX][fromY] = 0;
   
    if (finished != 0) {
        chess_state.current_turn = finished;
    } else {
        // 转换操作权
        chess_state.current_turn = (chess_state.current_turn == 1) ? 2 : 1;
        
        // 保存历史记录
        if (history_top < MAX_HISTORY - 1) {
            history_top++;
        } else {
            // 栈满时移除最旧记录（底部元素）
            memmove(history_stack, history_stack + 1, sizeof(HistoryRecord) * (MAX_HISTORY - 1));
        }
        history_stack[history_top].state = chess_state;
        history_stack[history_top].toX = toX;
        history_stack[history_top].toY = toY;
        
        // 判断是否死棋
        if (checkEndGame(&chess_state) != 0) {
            if (chess_state.current_turn == 1) {
                chess_state.current_turn = 4;
            } else {
                chess_state.current_turn = 3;    
            }
        }
        
        if (needComputeHelp != NULL && client_count == 1 && chess_state.current_turn == 2) {
            //只处理黑棋的自动运行
            int redIndex = -1;
            int blackIndex = -1;
            getRoleIndex(&redIndex, &blackIndex);
            if (redIndex != 1) {
                *needComputeHelp = 1;
            }
        }
    }
    generateStepMessage(stepMsg, toX, toY, &chess_state);
    // 广播
    forward_data(stepMsg, strlen(stepMsg), NULL, sockfd);
}

// 评估位置分数表（根据棋子类型和位置提供基础评分）
// [棋子类型][x][y] = 分数，0-16为红方，17-32为黑方
static const int position_score[33][9][10] = {
    // 0: 空位置（无分数）
    {},
    // 1: 红帅（九宫格内分数高）
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,50,80,50},
        {0,0,0,0,0,0,0,80,150,80},
        {0,0,0,0,0,0,0,50,80,50},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    // 2-3: 红仕（简化，与帅类似）
    [2 ... 3] = {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,40,0,40},
        {0,0,0,0,0,0,0,0,60,0},
        {0,0,0,0,0,0,0,40,0,40},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    // 4-5: 红相（河界内分数高）
    [4 ... 5] = {
        {0,0,0,0,0,0,0,40,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,30,0,0,0,30},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,40,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,30,0,0,0,30},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,40,0,0},
    },
    // 6-7: 红马（河口、棋盘中部分数高）
    [6 ... 7] = {
        {0,0,10,20,10,10,20,10,0,0},
        {0,20,30,40,30,30,40,30,20,0},
        {0,10,20,50,40,40,50,20,10,0},
        {0,0,30,40,60,60,40,30,0,0},
        {0,0,20,50,50,50,50,20,0,0},
        {0,0,30,40,60,60,40,30,0,0},
        {0,10,20,50,40,40,50,20,10,0},
        {0,20,30,40,30,30,40,30,20,0},
        {0,0,10,20,10,10,20,10,0,0}
    },
    // 8-9: 红车（通头位置、底线分数高）
    [8 ... 9] = {
        {40,30,30,30,30,30,30,30,40,0},
        {30,20,20,20,20,20,20,20,30,0},
        {30,20,20,20,20,20,20,20,30,0},
        {50,40,40,40,40,40,40,40,50,0},
        {50,40,40,40,40,40,40,40,50,0},
        {50,40,40,40,40,40,40,40,50,0},
        {30,20,20,20,20,20,20,20,30,0},
        {30,20,20,20,20,20,20,20,30,0},
        {40,30,30,30,30,30,30,30,40,0}
    },
    // 10-11: 红炮（炮位、底线分数高）
    [10 ... 11] = {
        {10,0,20,0,30,0,20,0,10,0},
        {0,20,0,30,0,30,0,20,0,0},
        {20,0,20,0,20,0,20,0,20,0},
        {0,30,0,40,0,40,0,30,0,0},
        {30,0,40,0,50,0,40,0,30,0},
        {0,30,0,40,0,40,0,30,0,0},
        {20,0,20,0,20,0,20,0,20,0},
        {0,20,0,30,0,30,0,20,0,0},
        {10,0,20,0,30,0,20,0,10,0}
    },
    // 12-16: 红兵（过河后分数递增）
    [12 ... 16] = {
        {0,150,100,80,50,30,20,0,0,0},
        {0,150,100,80,50,30,20,0,0,0},
        {0,150,100,80,50,30,20,0,0,0},
        {0,180,120,90,60,40,20,0,0,0},
        {0,180,120,90,60,40,20,0,0,0},
        {0,180,120,90,60,40,20,0,0,0},
        {0,150,100,80,50,30,20,0,0,0},
        {0,150,100,80,50,30,20,0,0,0},
        {0,150,100,80,50,30,20,0,0,0}
    },
    // 17: 黑将（与红帅对称）
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {50,80,50,0,0,0,0,0,0,0},
        {80,150,80,0,0,0,0,0,0,0},
        {50,80,50,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    // 18-19: 黑士（与红仕对称）
    [18 ... 19] = {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {40,0,40,0,0,0,0,0,0,0},
        {0,60,0,0,0,0,0,0,0,0},
        {40,0,40,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    // 20-21: 黑象（与红相对称）
    [20 ... 21] = {
        {0,0,40,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {30,0,0,0,30,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,40,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {30,0,0,0,30,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,40,0,0,0,0,0,0,0}
    },
    // 22-23: 黑马（与红马对称）
    [22 ... 23] = {
        {0,0,10,20,10,10,20,10,0,0},
        {0,20,30,40,30,30,40,30,20,0},
        {0,10,20,50,40,40,50,20,10,0},
        {0,0,30,40,60,60,40,30,0,0},
        {0,0,20,50,50,50,50,20,0,0},
        {0,0,30,40,60,60,40,30,0,0},
        {0,10,20,50,40,40,50,20,10,0},
        {0,20,30,40,30,30,40,30,20,0},
        {0,0,10,20,10,10,20,10,0,0}
    },
    // 24-25: 黑车（与红车对称）
    [24 ... 25] = {
        {0,40,30,30,30,30,30,30,30,40},
        {0,30,20,20,20,20,20,20,20,30},
        {0,30,20,20,20,20,20,20,20,30},
        {0,50,40,40,40,40,40,40,40,50},
        {0,50,40,40,40,40,40,40,40,50},
        {0,50,40,40,40,40,40,40,40,50},
        {0,30,20,20,20,20,20,20,20,30},
        {0,30,20,20,20,20,20,20,20,30},
        {0,40,30,30,30,30,30,30,30,40}
    },
    // 26-27: 黑炮（与红炮对称）
    [26 ... 27] = {
        {0,10,0,20,0,30,0,20,0,10},
        {0,0,20,0,30,0,30,0,20,0},
        {0,20,0,20,0,20,0,20,0,20},
        {0,0,30,0,40,0,40,0,30,0},
        {0,30,0,40,0,50,0,40,0,30},
        {0,0,30,0,40,0,40,0,30,0},
        {0,20,0,20,0,20,0,20,0,20},
        {0,0,20,0,30,0,30,0,20,0},
        {0,10,0,20,0,30,0,20,0,10}
    },
    // 28-32: 黑卒（与红兵对称）
    [28 ... 32] = {
        {0,0,0,20,30,50,80,100,150,0},
        {0,0,0,20,30,50,80,100,150,0},
        {0,0,0,20,30,50,80,100,150,0},
        {0,0,0,20,40,60,90,120,180,0},
        {0,0,0,20,40,60,90,120,180,0},
        {0,0,0,20,40,60,90,120,180,0},
        {0,0,0,20,30,50,80,100,150,0},
        {0,0,0,20,30,50,80,100,150,0},
        {0,0,0,20,30,50,80,100,150,0}
    }
};

// 棋子基础价值
static const int piece_value[33] = {
    0,    // 0: 空
    10000,// 1: 帅
    200,  // 2: 仕
    200,  // 3: 仕
    250,  // 4: 相
    250,  // 5: 相
    450,  // 6: 马
    450,  // 7: 马
    900,  // 8: 车
    900,  // 9: 车
    450,  // 10: 炮
    450,  // 11: 炮
    100,  // 12: 兵
    100,  // 13: 兵
    100,  // 14: 兵
    100,  // 15: 兵
    100,  // 16: 兵
    10000,// 17: 将
    200,  // 18: 士
    200,  // 19: 士
    250,  // 20: 象
    250,  // 21: 象
    450,  // 22: 马
    450,  // 23: 马
    900,  // 24: 车
    900,  // 25: 车
    450,  // 26: 炮
    450,  // 27: 炮
    100,  // 28: 卒
    100,  // 29: 卒
    100,  // 30: 卒
    100,  // 31: 卒
    100   // 32: 卒
};

// 评估当前棋盘分数（正值为黑方优势，负值为红方优势）
static int evaluate_board(ChessState *state) {
    int score = 0;
    
    // 检查游戏结束状态
    int end_result = checkEndGame(state);
    if (end_result == 1) return -100000;  // 红方胜
    if (end_result == 2) return 100000;   // 黑方胜
    
    // 计算棋子价值和位置价值
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 9; x++) {
            int piece = state->board[x][y];
            if (piece == 0) continue;
            
            // 黑方棋子加分，红方棋子减分
            if (piece >= 17) {
                score += 1.5 * piece_value[piece];
                score += position_score[piece][x][y];
            } else {
                score -= 1.5 * piece_value[piece];
                score -= position_score[piece][x][y];
            }
        }
    }
    
    // 检查将军状态（将军方加分）
    int red_king_x = -1, red_king_y = -1;
    int black_king_x = -1, black_king_y = -1;
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 9; x++) {
            if (state->board[x][y] == 1) {
                red_king_x = x;
                red_king_y = y;
            } else if (state->board[x][y] == 17) {
                black_king_x = x;
                black_king_y = y;
            }
        }
    }
    
    if (isKingInCheck(red_king_x, red_king_y, 1, state)) {
        score += 600;  // 黑方将军红方
    }
    if (isKingInCheck(black_king_x, black_king_y, 2, state)) {
        score -= 600;  // 红方将军黑方
    }
    
    return score;
}

// 检查指定位置的棋子是否会被敌方吃掉
// attacker_role: 1=红方攻击, 2=黑方攻击
static int is_piece_in_danger(int x, int y, int attacker_role, ChessState *state) {
    int target_piece = state->board[x][y];
    if (target_piece == 0) {
        return 0;  // 空位置无风险
    }
    
    // 遍历所有攻击方棋子
    for (int ax = 0; ax < 9; ax++) {
        for (int ay = 0; ay < 10; ay++) {
            int attacker = state->board[ax][ay];
            if (attacker == 0) continue;
            
            // 检查是否为攻击方棋子
            if ((attacker_role == 1 && attacker < 17) ||  // 红方攻击
                (attacker_role == 2 && attacker >= 17)) { // 黑方攻击
                
                // 临时切换回合检查是否能吃掉目标
                int original_turn = state->current_turn;
                state->current_turn = attacker_role;
                int can_capture = isValidPieceMove(ax, ay, x, y, attacker, state);
                state->current_turn = original_turn;
                
                if (can_capture) {
                    return 1;
                }
            }
        }
    }
    return 0;
}

// 递归搜索最佳走法（优化版）
static int search_best_move(ChessState *state, int depth, int alpha, int beta, int is_black_turn) {
    // 达到搜索深度或游戏结束
    if (depth == 0 || checkEndGame(state) != 0) {
        return evaluate_board(state);
    }
    
    int best_score = is_black_turn ? -1000000 : 1000000;
    int has_valid_move = 0;
    
    // 遍历所有可能的移动
    for (int fromX = 0; fromX < 9; fromX++) {
        for (int fromY = 0; fromY < 10; fromY++) {
            int piece = state->board[fromX][fromY];
            if (piece == 0) continue;
            
            // 检查是否当前回合的棋子
            if ((is_black_turn && piece < 17) || (!is_black_turn && piece >= 17)) {
                continue;
            }
            
            // 记录当前棋子价值（用于风险评估）
            int current_piece_value = piece_value[piece];
            
            // 尝试所有可能的目标位置
            for (int toX = 0; toX < 9; toX++) {
                for (int toY = 0; toY < 10; toY++) {
                    // 检查移动是否有效
                    //ClientRole role = is_black_turn ? ROLE_BLACK_PLAYER : ROLE_RED_PLAYER;
                    int result_move = isValidPieceMove(fromX, fromY, toX, toY, piece, state);
                    if (!result_move) {
                        continue;
                    }
                   
                    has_valid_move = 1;
                    // 保存原始状态
                    int captured_piece = state->board[toX][toY];
                    int original_turn = state->current_turn;
                    
                    // 执行移动
                    state->board[toX][toY] = piece;
                    state->board[fromX][fromY] = 0;
                    state->current_turn = is_black_turn ? 1 : 2;
                    
                    // 计算即时风险奖励/惩罚
                    int risk_adjust = 0;
                    if (is_black_turn) {
                        // 黑方回合：检查移动后是否会被红方下一步吃掉
                        if (is_piece_in_danger(toX, toY, 1, state)) {  // 1表示红方攻击
                            risk_adjust -= current_piece_value * 7 / 10;  // 被吃风险惩罚70%价值
                        }
                        // 移动后脱离危险的奖励
                        if (is_piece_in_danger(fromX, fromY, 1, state) && 
                            !is_piece_in_danger(toX, toY, 1, state)) {
                            risk_adjust += current_piece_value * 3 / 10;  // 脱离危险奖励30%价值
                        }
                    } else {
                        // 红方回合：检查移动后是否会被黑方下一步吃掉
                        if (is_piece_in_danger(toX, toY, 2, state)) {  // 2表示黑方攻击
                            risk_adjust += current_piece_value * 7 / 10;  // 红方棋子被吃对黑方有利
                        }
                    }
                    
                    // 递归搜索（加入风险调整）
                    int score = search_best_move(state, depth - 1, alpha, beta, !is_black_turn) + risk_adjust;
                    
                    // 恢复状态
                    state->board[fromX][fromY] = piece;
                    state->board[toX][toY] = captured_piece;
                    state->current_turn = original_turn;
                    
                    // 极大极小值剪枝
                    if (is_black_turn) {
                        if (score > best_score) {
                            best_score = score;
                        }
                        if (best_score > alpha) {
                            alpha = best_score;
                        }
                        if (beta <= alpha) {
                            break;  // beta剪枝
                        }
                    } else {
                        if (score < best_score) {
                            best_score = score;
                        }
                        if (best_score < beta) {
                            beta = best_score;
                        }
                        if (beta <= alpha) {
                            break;  // alpha剪枝
                        }
                    }
                }
                if ((is_black_turn && beta <= alpha) || (!is_black_turn && beta <= alpha)) {
                    break;  // 剪枝，退出循环
                }
            }
            if ((is_black_turn && beta <= alpha) || (!is_black_turn && beta <= alpha)) {
                break;  // 剪枝，退出循环
            }
        }
        if ((is_black_turn && beta <= alpha) || (!is_black_turn && beta <= alpha)) {
            break;  // 剪枝，退出循环
        }
    }
    
    // 如果没有有效走法，返回当前评估值
    if (!has_valid_move) {
        return evaluate_board(state);
    }
    
    return best_score;
}


// 计算机走棋（黑方）
void computerMove() {
    int fromX, fromY, toX, toY;
  
    int best_score = -1000000;
    int found = 0;
    // 复制当前状态用于搜索
    ChessState temp_state = chess_state;

    // 遍历所有可能的移动
    for (int fX = 0; fX < 9; fX++) {
        for (int fY = 0; fY < 10; fY++) {
            int piece = temp_state.board[fX][fY];
            
            if (piece == 0 || piece < 17) {
                continue;  // 只考虑黑方棋子
            }
            
            // 尝试所有可能的目标位置
            for (int tX = 0; tX < 9; tX++) {
                for (int tY = 0; tY < 10; tY++) {
                    // 检查移动有效性
                    if (!isValidMove(fX, fY, tX, tY, ROLE_BLACK_PLAYER) ||
                        !isValidPieceMove(fX, fY, tX, tY, piece, &temp_state)) {
                        continue;
                    }
                    
                    // 保存原始状态
                    int captured = temp_state.board[tX][tY];
                    int original_turn = temp_state.current_turn;
                    
                    // 执行移动
                    temp_state.board[tX][tY] = piece;
                    temp_state.board[fX][fY] = 0;
                    temp_state.current_turn = 1;  // 模拟红方回合
                    
                    // 搜索评分
                    int score = search_best_move(&temp_state, 3, -1000000, 1000000, 0);
                    
                    // 恢复状态
                    temp_state.board[fX][fY] = piece;
                    temp_state.board[tX][tY] = captured;
                    temp_state.current_turn = original_turn;
                    
                    // 更新最佳走法
                    if (score > best_score) {
                        best_score = score;
                        fromX = fX;
                        fromY = fY;
                        toX = tX;
                        toY = tY;
                        found = 1;
                    }
                }
            }
        }
    }

    pthread_mutex_lock(&chess_mutex);
    // 如果没有找到有效走法（理论上不会发生）
    if (found == 1 && chess_state.current_turn == 2) {
        log_message("score=%d", best_score);
        moveChess(fromX, fromY, toX, toY, NULL);
    }    
    pthread_mutex_unlock(&chess_mutex);
}

// 处理移动指令 
void handleMoveCommand(char *buffer, struct sockaddr_in *sender_addr) {
    int fromX, fromY, toX, toY;    
    int needComputeMove = 0;
    
    if (sscanf(buffer, MOVE_PREFIX "%d,%d,%d,%d", &fromX, &fromY, &toX, &toY) != 4) {
        log_message("Invalid move format");
        return;
    }
    
    if (chess_state.current_turn > 2) {
        return;  
    }

    ClientRole senderRole = ROLE_NONE;
    for (int i = 0; i < client_count; i++) {
        if (memcmp(&clients[i].addr, sender_addr, sizeof(struct sockaddr_in)) == 0) {
            senderRole = clients[i].role;
            break;
        }
    }

    if (senderRole != ROLE_RED_PLAYER && chess_state.current_turn == 1) {
        log_message("Not red tried to move piece in red");
        return;
    }
    
    if (senderRole != ROLE_BLACK_PLAYER && chess_state.current_turn == 2) {
        log_message("Not black tried to move piece in black");
        return;
    }

    pthread_mutex_lock(&chess_mutex);
    if (isValidMove(fromX, fromY, toX, toY, senderRole)) {
        moveChess(fromX, fromY, toX, toY, &needComputeMove);        
        log_message("Valid move executed: %s", buffer);
    } else {
        log_message("Invalid move attempted: %s", buffer);
    }
    pthread_mutex_unlock(&chess_mutex);
    
    //检查是否需要机器帮助
    if (needComputeMove == 1) {
        if (history_top == 0) {
            //第一步用固定模式
            if (chess_state.board[4][7] != 0) {
                fromX = 1;
                fromY = 0;
                toX = 2;
                toY = 2;
            } else {
                fromX = 1;
                fromY = 2;
                toX = 4;
                toY = 2;
            }
            pthread_mutex_lock(&chess_mutex);
            moveChess(fromX, fromY, toX, toY, NULL);
            pthread_mutex_unlock(&chess_mutex);            
        } else {
            if (history_top == 2) {
                if (chess_state.board[4][2] == 0 &&
                    chess_state.board[5][2] == 0 &&
                    chess_state.board[6][2] == 0 &&
                    chess_state.board[7][2] == 27 &&
                    chess_state.board[4][3] == 29) {
                    int has_enemy = 0;
                    for (int tX = 0; tX < 9; tX++) {
                        for (int tY = 0; tY < 5; tY++) {
                            if (chess_state.board[tX][tY] != 0 && chess_state.board[tX][tY] < 17) {
                                has_enemy = 1;
                            }
                        }
                    }
                    if (has_enemy == 0) {
                        fromX = 7;
                        fromY = 2;
                        toX = 4;
                        toY = 2;
                        pthread_mutex_lock(&chess_mutex);
                        moveChess(fromX, fromY, toX, toY, NULL);
                        pthread_mutex_unlock(&chess_mutex);  
                        return;
                    }
                }
            }
            
            computerMove();
        }
    }
}

//////////////////// 主函数 /////////////////////

int main() {
    struct sockaddr_in server_addr, client_addr;
    char buffer[BUFFER_SIZE];
    socklen_t client_len = sizeof(client_addr);
    red_device_id[0] = '\0';
    black_device_id[0] = '\0';

    initChessState();
    // 创建socket 
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 绑定地址 
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    log_message("Waiting for clients...");
    
    // 启动心跳检查线程
    pthread_t tid;
    if (pthread_create(&tid, NULL, heartbeat_check_thread, NULL) != 0) {
        perror("pthread_create failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }    
    
    while (1) {
        int len = recvfrom(sockfd, buffer, BUFFER_SIZE, 0,
                           (struct sockaddr *)&client_addr, &client_len);

        if (len < 0) {
            perror("recvfrom failed");
            continue;
        }
        buffer[len] = '\0';

        // 处理连接请求
        if (strstr(buffer, CONNECT_PREFIX) == buffer) {
            char * device_id = buffer + strlen(CONNECT_PREFIX);
            log_message("Received connect request from client");
            add_client(&client_addr, device_id);
            continue;
        }

        // 处理心跳包
        if (strstr(buffer, HEARTBEAT_PREFIX) == buffer) {
            int found = 0;
            char * device_id = buffer + strlen(HEARTBEAT_PREFIX);
            //log_message("heartbeat %s %s:%d", device_id, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
            pthread_mutex_lock(&clients_mutex);
            for (int i = 0; i < client_count; i++) {
                if (memcmp(&clients[i].addr, &client_addr, sizeof(struct sockaddr_in)) == 0) {
                    clients[i].last_heartbeat = time(NULL);  // 更新心跳时间
                    found = 1;
                    break;
                }
            }
            pthread_mutex_unlock(&clients_mutex);
            
            if (found == 0) {
                log_message("Recover connect request from client");
                add_client(&client_addr, device_id);
            }
            continue;
        }

        // 处理移动指令 
        if (strstr(buffer, MOVE_PREFIX) == buffer) {
            handleMoveCommand(buffer, &client_addr);
            continue;
        }

        //  处理重置棋盘命令（只有红方和黑方玩家可以发送）
        if (strcmp(buffer, RESET_COMMAND) == 0 || strcmp(buffer, BACK_COMMAND) == 0) {
            ClientRole senderRole = ROLE_NONE;
            for (int i = 0; i < client_count; i++) {
                if (memcmp(&clients[i].addr, &client_addr, sizeof(struct sockaddr_in)) == 0) {
                    senderRole = clients[i].role;
                    break;
                }
            }
            if (senderRole == ROLE_RED_PLAYER || senderRole == ROLE_BLACK_PLAYER) {
                if (strcmp(buffer, RESET_COMMAND) == 0) {
                    resetBoard();
                }
                if (strcmp(buffer, BACK_COMMAND) == 0) {
                    backBoard(senderRole);
                }
            } else {
                log_message("Spectator tried to reset board");
            }
            continue;
        }

        // 转发语音数据 
        forward_data(buffer, len, &client_addr, sockfd);
        log_message("Received and forwarded %d bytes from client", len);
    }

    close(sockfd);
    return 0;
}

